home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 7
/
PC World Interactive 7.iso
/
program
/
cprog.EXE
/
CC_1.ZIP
/
CC32.C
< prev
next >
Wrap
Text File
|
1990-11-22
|
8KB
|
316 lines
/*
** Note: Return true if value loaded, false if not;
*/
heir13(lval) int lval[]; {
int k;
char *ptr;
if (match("++")) { /* ++lval */
if(heir13(lval)==0) {
needlval();
return 0;
}
step(inc, lval);
return 0;
}
else if (match("--")) { /* --lval */
if(heir13(lval)==0) {
needlval();
return 0;
}
step(dec, lval);
return 0;
}
else if (match("~")) { /* ~ */
if(heir13(lval)) rvalue(lval);
com();
lval[4] = ~lval[4];
return 0;
}
else if (match("!")) { /* ! */
if(heir13(lval)) rvalue(lval);
lneg();
lval[4] = !lval[4];
return 0;
}
else if (match("-")) { /* unary - */
if(heir13(lval)) rvalue(lval);
neg();
lval[4] = -lval[4];
return 0;
}
else if (match("*")) { /* unary * */
if(heir13(lval)) rvalue(lval);
if(ptr=lval[0]) lval[1]=ptr[TYPE];
else lval[1]=CINT;
lval[2]=0; /* flag as not pointer or array */
lval[3]=0; /* flag as not constant */
return 1;
}
else if (match("&")) { /* unary & */
if(heir13(lval)==0) {
error("illegal address");
return 0;
}
ptr=lval[0];
lval[2]=ptr[TYPE];
if(lval[1]) return 0;
/* global & non-array */
address(ptr);
lval[1]=ptr[TYPE];
return 0;
}
else if (match("(int)")) { /* (int) cast */
if(heir13(lval)) rvalue(lval);
lval[0]=castint;
lval[1]=CINT;
lval[2]=0;
return 0;
}
else if (match("(char)")) { /* (char) cast */
if(heir13(lval)) rvalue(lval);
lval[0]=castchar;
lval[1]=CCHAR;
lval[2]=0;
return 0;
}
else if (match("(int *)")) { /* (int *) cast */
if(heir13(lval)) rvalue(lval);
lval[0]=castpint;
lval[1]=0;
lval[2]=CINT;
return 0;
}
else if (match("(char *)")) { /* (char *) cast */
if(heir13(lval)) rvalue(lval);
lval[0]=castpchar;
lval[1]=0;
lval[2]=CCHAR;
return 0;
}
else {
k=heir14(lval);
if(match("++")) { /* lval++ */
if(k==0) {
needlval();
return 0;
}
step(inc, lval);
dec(lval[2]>>2);
return 0;
}
else if(match("--")) { /* lval-- */
if(k==0) {
needlval();
return 0;
}
step(dec, lval);
inc(lval[2]>>2);
return 0;
}
else return k;
}
}
heir14(lval) int *lval; {
int k, const, val, lval2[8];
char *ptr, *before, *start;
k=primary(lval);
ptr=lval[0];
blanks();
if((ch=='[')|(ch=='(')) {
lval[5]=1; /* secondary register will be used */
while(1) {
if(match("[")) { /* [subscript] */
if(ptr==0) {
error("can't subscript");
junk();
needtoken("]");
return 0;
}
else if(ptr[IDENT]==POINTER) rvalue(lval);
else if(ptr[IDENT]!=ARRAY) {
error("can't subscript");
k=0;
}
setstage(&before, &start);
lval2[3]=0;
plunge2(0, 0, heir1, lval2, lval2); /* lval2 deadend */
needtoken("]");
/* -- beginning of new code -- */
if(match("[")) { /* we have more dimensions */
if(ptr[NDIM] < 2 ) {
error("too many dimension"); /* variable declared with */
junk(); /* less dimensions */
needtoken("]");
return 0;
}
if(lval2[3]) { /* Test for index being constant */
clearstage(before, 0); /* ignore code generated by plunge2 */
ol("XCHG AX,BX");
/* const(lval2[4]); */
ot("MOV AX,");
outdec(lval2[4]);
nl();
}
ol("PUSH BX");
if((lval2[3] == 0) | lval2[4]) {
if(ptr[TYPE] == CINT) /* Get 2nd dimension size */
const2(ptr[CDIM] << LBPW); /* and adjust for type size */
else
const2(ptr[CDIM]);
mult(); /* AX gets C * i1 */
}
setstage(&before, &start);
lval2[3] = 0; /* parse subscript 2 expression */
plunge2(0, 0, heir1, lval2, lval2);
needtoken("]");
if(lval2[3]) { /* if index is a constant */
clearstage(before, 0); /* dump plunge2 generated code */
if(lval2[4]) /* if index is non-zero */
if(ptr[TYPE] == CINT) {
ot("ADD AX,");
outdec(lval2[4] << LBPW);
nl();
}
else {
ot("ADD AX,");
outdec(lval2[4]);
}
}
else {
if(ptr[TYPE] == CINT)
doublereg();
add(); /* AX gets C*i1 + i2 */
}
ol("POP BX");
/* retrieve array base from stack */
add(); /* calculate segment address of target */
}
else { /* only one dimension */
/* -- end of new code -- */
if(lval2[3]) {
clearstage(before,0);
if(lval2[4]) {
if(ptr[TYPE]==CINT) const2(lval2[4]<<LBPW);
else const2(lval2[4]);
add();
}
}
else {
if(ptr[TYPE]==CINT) doublereg();
add();
}
}
lval[0]=lval[2]=0;
lval[1]=ptr[TYPE];
k=1;
}
else if(match("(")) { /* function(...) */
if(ptr==0) callfunction(0); /* call to an absolute address */
else if(ptr[IDENT]!=FUNCTION) {
rvalue(lval);
callfunction(0);
}
else callfunction(ptr);
k=lval[0]=lval[3]=0;
}
else return k;
}
}
if(ptr==0) return k; /* if constant, return */
if(ptr[IDENT]==FUNCTION) { /* if function name without "()", gen address */
address(ptr);
return 0;
}
return k;
}
/*
** fixed per A. Macpherson letter, DDJ #81
*/
primary(lval) int *lval; {
char *ptr;
int k;
if(match("(")) { /* (expression) */
do
k=heir1(lval);
while(match(",")); /* comma operator */
needtoken(")");
return k;
}
putint(0, lval, 8<<LBPW); /* clear lval array */
if(symname(ssname, YES)) {
if(ptr=findloc(ssname)) {
#ifdef STGOTO
if(ptr[IDENT]==LABEL) {
experr();
return 0;
}
#endif
ptr[STATUS] |= USED;
getloc(ptr);
lval[0]=ptr;
lval[1]=ptr[TYPE];
if(ptr[IDENT]==POINTER) {
lval[1]=CINT;
lval[2]=ptr[TYPE];
}
if(ptr[IDENT]==ARRAY) {
lval[2]=ptr[TYPE];
return 0;
}
else return 1;
}
if(ptr=findglb(ssname)) {
ptr[STATUS] |= USED;
if(ptr[IDENT]!=FUNCTION) {
lval[0]=ptr;
lval[1]=0;
if(ptr[IDENT]!=ARRAY) {
if(ptr[IDENT]==POINTER) lval[2]=ptr[TYPE];
return 1;
}
address(ptr);
lval[1]=lval[2]=ptr[TYPE];
return 0;
}
}
/* implicitly define (if necessary) */
ptr=addsym(ssname, FUNCTION, CINT, 0, &glbptr, STATIC, 0, 0);
ptr[STATUS] |= USED;
lval[0]=ptr;
lval[1]=0;
return 0;
}
if(constant(lval)==0) experr();
return 0;
}
experr() {
error("invalid expression");
const(0);
junk();
}
callfunction(ptr) char *ptr; { /* symbol table entry or 0 */
int nargs, const, val;
nargs=0;
blanks(); /* already saw open paren */
if(ptr==0) push(); /* calling AX */
while(streq(lptr,")")==0) {
if(endst()) break;
expression(&const, &val);
if(ptr==0) swapstk(); /* don't push addr */
push(); /* push argument */
nargs=nargs+BPW; /* count args*BPW */
if (match(",")==0) break;
}
needtoken(")");
if(streq(ptr+NAME, "CCARGC")==0) loadargc(nargs>>LBPW);
if(ptr) call(ptr+NAME);
else callstk();
csp=modstk(csp+nargs);
}